<template>
	<view class="container">
		<!-- 顶部粘性区域：搜索 + 筛选 -->
		<view class="sticky-header">
		<!-- 搜索栏 -->
		<view class="search-bar">
				<view class="search-input-wrapper">
					<text class="search-icon">🔎</text>
			<input 
				class="search-input" 
				v-model="searchKeyword" 
				placeholder="搜索学生姓名或手机号"
				@input="onSearch"
			/>
				</view>
			</view>

			<!-- 筛选器 -->
			<view class="filter-section">
				<view class="filter-tabs">
					<view
						class="filter-tab"
						:class="{ active: currentFilter === 'all' }"
						@click="setFilter('all')"
					>
						<text class="tab-text">全部学生</text>
					</view>
					<view
						class="filter-tab"
						:class="{ active: currentFilter === 'active' }"
						@click="setFilter('active')"
					>
						<text class="tab-text">有剩余课时</text>
					</view>
					<view
						class="filter-tab"
						:class="{ active: currentFilter === 'inactive' }"
						@click="setFilter('inactive')"
					>
						<text class="tab-text">课时用完</text>
					</view>
				</view>
			</view>
		</view>

		<!-- 统计卡片 -->
		<view class="stats-cards">
			<view class="stat-card glass">
				<view class="stat-icon">
					<text class="icon-text">👥</text>
				</view>
				<view class="stat-content">
					<text class="stat-number gradient-text">{{ totalStudents }}</text>
					<text class="stat-label">总学生数</text>
				</view>
			</view>
			<view class="stat-card glass">
				<view class="stat-icon">
					<text class="icon-text">⏰</text>
				</view>
				<view class="stat-content">
					<text class="stat-number gradient-text">{{ totalUsedHours }}</text>
					<text class="stat-label">已用课时</text>
				</view>
			</view>
			<view class="stat-card glass">
				<view class="stat-icon">
					<text class="icon-text">📚</text>
				</view>
				<view class="stat-content">
					<text class="stat-number gradient-text">{{ totalRemainingHours }}</text>
					<text class="stat-label">剩余课时</text>
				</view>
			</view>
		</view>

		<!-- 学生列表 / 骨架屏 -->
		<view v-if="loading" class="skeleton-list">
			<view class="skeleton-item" v-for="n in 3" :key="n">
				<view class="skeleton-avatar shimmer"></view>
				<view class="skeleton-lines">
					<view class="skeleton-line shimmer" style="width: 50%"></view>
					<view class="skeleton-line shimmer" style="width: 70%"></view>
					<view class="skeleton-line shimmer" style="width: 40%"></view>
				</view>
			</view>
		</view>

		<view v-else class="student-list">
			<view class="student-item" v-for="(student, index) in filteredStudents" :key="student.id" :style="{ animationDelay: (index * 50) + 'ms' }">
				<view class="student-info">
					<view class="student-avatar-wrap">
						<image class="student-avatar" :src="'/static/default-avatar.png'" mode="aspectFill"></image>
						<view class="avatar-ring"></view>
					</view>
					<view class="student-details">
						<view class="student-header">
							<text class="student-name">{{ student.studentName }}</text>
							<view class="student-status glow" :class="{ 'active': student.remainingHours > 0, 'inactive': student.remainingHours <= 0 }">
								<text class="status-text">{{ student.remainingHours > 0 ? '有课时' : '无课时' }}</text>
							</view>
						</view>
						<text class="student-phone">{{ student.parentPhone }}</text>
						<view class="student-hours">
							<text class="hours-item">总课时: {{ student.totalHours || 0 }}</text>
							<text class="hours-item">已用: {{ student.usedHours || 0 }}</text>
							<text class="hours-item remaining">剩余: {{ student.remainingHours || 0 }}</text>
						</view>
						<view class="progress-row" v-if="(student.totalHours || 0) > 0">
							<view class="progress-bar">
								<view class="progress-fill" :style="{ width: Math.min(100, Math.max(0, Math.round(((student.usedHours || 0) / (student.totalHours || 1)) * 100))) + '%' }"></view>
							</view>
							<text class="progress-text">{{ Math.min(100, Math.max(0, Math.round(((student.usedHours || 0) / (student.totalHours || 1)) * 100))) }}%</text>
						</view>
					</view>
				</view>
				<view class="student-actions">
					<button class="action-btn edit-btn" @click="editStudent(student)">✏️ 编辑</button>
					<button class="action-btn detail-btn" @click="viewDetails(student)">🔎 详情</button>
				</view>
			</view>
		</view>

		<!-- 空状态 -->
		<view v-if="!loading && filteredStudents.length === 0" class="empty-section">
			<text class="empty-icon">👤</text>
			<text class="empty-text">暂无学生数据</text>
			<text class="empty-desc">学生需通过微信小程序登录后显示在此</text>
		</view>

		<!-- 编辑学生弹窗 -->
		<view class="modal fade-in" v-if="showEditModal" @click="closeEditModal">
			<view class="modal-content glass slide-up" @click.stop>
				<view class="modal-header">
					<text class="modal-title">编辑学生信息</text>
					<text class="modal-close" @click="closeEditModal">×</text>
				</view>

				<!-- 概要信息 -->
				<view class="modal-summary">
					<view class="summary-avatar">
						<image class="avatar" :src="'/static/default-avatar.png'" mode="aspectFill"></image>
					</view>
					<view class="summary-info">
						<text class="summary-name">{{ editForm.name || '未命名' }}</text>
						<text class="summary-phone">{{ editForm.phone || '未填写手机号' }}</text>
						<view class="summary-chips">
							<text class="chip">总 {{ editForm.totalHours || 0 }}</text>
							<text class="chip">已用 {{ editForm.usedHours || 0 }}</text>
							<text class="chip primary">剩余 {{ (editForm.totalHours || 0) - (editForm.usedHours || 0) }}</text>
						</view>
					</view>
				</view>
				
				<view class="form">
					<view class="form-item">
						<text class="form-label">学生姓名</text>
						<view class="input-wrapper">
							<text class="prefix">👤</text>
							<input class="form-input" v-model="editForm.name" placeholder="请输入学生姓名" />
						</view>
					</view>
					<view class="form-item">
						<text class="form-label">手机号</text>
						<view class="input-wrapper">
							<text class="prefix">📱</text>
							<input class="form-input" v-model="editForm.phone" placeholder="请输入手机号" type="number" maxlength="11" />
						</view>
					</view>
					<view class="form-item two-col">
						<view class="col">
							<text class="form-label">总课时</text>
							<view class="input-wrapper with-stepper">
								<button class="stepper" @click="step('totalHours', -1)">-</button>
								<input class="form-input" v-model="editForm.totalHours" placeholder="请输入总课时" type="number" />
								<button class="stepper" @click="step('totalHours', 1)">+</button>
							</view>
						</view>
						<view class="col">
							<text class="form-label">已用课时</text>
							<view class="input-wrapper with-stepper">
								<button class="stepper" @click="step('usedHours', -1)">-</button>
								<input class="form-input" v-model="editForm.usedHours" placeholder="请输入已用课时" type="number" />
								<button class="stepper" @click="step('usedHours', 1)">+</button>
							</view>
						</view>
					</view>
					<view class="form-item">
						<text class="form-label">剩余课时</text>
						<text class="form-calculated">{{ (editForm.totalHours || 0) - (editForm.usedHours || 0) }}</text>
					</view>
				</view>
				
				<view class="modal-actions">
					<button class="cancel-btn" @click="closeEditModal" :disabled="_submitLock">取消</button>
					<button class="confirm-btn" @click="confirmEditStudent" :disabled="_submitLock">
						<text v-if="_submitLock">⏳ 正在保存...</text>
						<text v-else>💾 保存修改</text>
					</button>
				</view>
			</view>
		</view>
	</view>
</template>

<script>
import { getApiUrl, API_CONFIG, apiRequest } from '@/config/api.js'

export default {
	data() {
		return {
			students: [],
			searchKeyword: '',
			currentFilter: 'all',
			loading: false,
			editForm: {
				id: null,
				name: '',
				phone: '',
				totalHours: 0,
				usedHours: 0,
				remainingHours: 0,
				role: 0
			},
			showEditModal: false,
			// 原始值用于计算差分与校验
			_original: {
				name: '',
				phone: '',
				totalHours: 0,
				usedHours: 0,
				remainingHours: 0
			},
			_submitLock: false
		}
	},
	computed: {
		filteredStudents() {
			let filtered = this.students
			
			// 搜索过滤
			if (this.searchKeyword) {
				filtered = filtered.filter(student => 
					(student.studentName && student.studentName.includes(this.searchKeyword)) ||
					(student.parentPhone && student.parentPhone.includes(this.searchKeyword))
				)
			}

			// 课时状态过滤
			if (this.currentFilter === 'active') {
				filtered = filtered.filter(student => student.remainingHours > 0)
			} else if (this.currentFilter === 'inactive') {
				filtered = filtered.filter(student => student.remainingHours <= 0)
			}
			
			return filtered
		},
		totalStudents() {
			return this.students.length
		},
		totalUsedHours() {
			return this.students.reduce((total, student) => total + (student.usedHours || 0), 0)
		},
		totalRemainingHours() {
			return this.students.reduce((total, student) => total + (student.remainingHours || 0), 0)
		}
	},
	onLoad() {
		this.loadStudents()
	},
	methods: {
		async loadStudents() {
			this.loading = true
			console.log('开始加载学生列表...')

			try {
				const token = uni.getStorageSync('token')
				console.log('Token:', token)

				// 构建查询参数
				const queryParams = {}
				if (this.searchKeyword) queryParams.keyword = this.searchKeyword
				queryParams.filter = this.currentFilter

				// 构建URL带查询参数
				let url = getApiUrl(API_CONFIG.ENDPOINTS.LESSON_ADMIN_STUDENTS)
				const queryString = Object.keys(queryParams)
					.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(queryParams[key])}`)
					.join('&')

				if (queryString) {
					url += '?' + queryString
				}

				const response = await apiRequest({
					url: url,
					method: 'GET',
					header: {
						'Content-Type': 'application/json',
						'Authorization': `Bearer ${token}`
					}
				})

				console.log('学生列表API响应:', response)

				if (response.code === 200) {
					this.students = response.data || []
					console.log('学生列表加载成功:', this.students)
					console.log('第一个学生数据示例:', this.students[0])
					// 检查数据结构
					if (this.students.length > 0) {
						const firstStudent = this.students[0]
						console.log('学生字段检查:', {
							id: firstStudent.id,
							studentName: firstStudent.studentName,
							parentPhone: firstStudent.parentPhone,
							totalHours: firstStudent.totalHours,
							usedHours: firstStudent.usedHours,
							remainingHours: firstStudent.remainingHours
						})
					}
				} else {
					console.error('学生列表加载失败:', response.message)
					uni.showToast({
						title: response.message || '获取学生列表失败',
						icon: 'none'
					})
				}
			} catch (error) {
				console.error('加载学生列表失败:', error)
				uni.showToast({
					title: '网络错误，请重试',
					icon: 'none'
				})
			} finally {
				this.loading = false
			}
		},

		onSearch() {
			// 防抖搜索
			clearTimeout(this.searchTimer)
			this.searchTimer = setTimeout(() => {
				this.loadStudents()
			}, 500)
		},

		setFilter(filter) {
			this.currentFilter = filter
			this.loadStudents()
		},

		viewDetails(student) {
			uni.navigateTo({
				url: `/pages/admin/student-history?studentId=${student.id}&studentName=${encodeURIComponent(student.studentName)}`
			})
		},

		async fetchUserRole(userId) {
			try {
				const token = uni.getStorageSync('token')
				const res = await apiRequest({
					url: getApiUrl(`${API_CONFIG.ENDPOINTS.LESSON_ADMIN_STATS.replace('/stats','')}/getUserById`) + `?userId=${userId}`,
					method: 'GET',
					header: {
						'Content-Type': 'application/json',
						'Authorization': `Bearer ${token}`
					}
			})
				if (res.code === 200 && res.data) {
					this.editForm.role = res.data.role != null ? res.data.role : 0
				} else {
					this.editForm.role = 0
				}
			} catch (e) {
				this.editForm.role = 0
			}
		},

		editStudent(student) {
			this.editForm = {
				id: student.id,
				name: student.studentName || '',
				phone: student.parentPhone || '',
				totalHours: student.totalHours || 0,
				usedHours: student.usedHours || 0,
				remainingHours: student.remainingHours || 0,
				role: 0
			}
			this._original = {
				name: this.editForm.name,
				phone: this.editForm.phone,
				totalHours: this.editForm.totalHours,
				usedHours: this.editForm.usedHours,
				remainingHours: this.editForm.remainingHours
			}
			this.showEditModal = true
			// 异步拉取role，避免更新时role为空
			this.fetchUserRole(student.id)
		},

		step(field, delta) {
			// 依据业务：不允许低于原始值；并保证非负与逻辑关系
			const toNumber = v => (v === '' || v === null || v === undefined) ? 0 : Number(v)
			let value = toNumber(this.editForm[field]) + delta
			const minByRule = field === 'totalHours' ? this._original.totalHours : (field === 'usedHours' ? this._original.usedHours : 0)
			if (!Number.isFinite(value)) value = minByRule
			if (value < minByRule) value = minByRule
			if (value < 0) value = 0
			this.editForm[field] = value
			// 关联约束：已用不能大于总课时
			if (field === 'totalHours' && toNumber(this.editForm.usedHours) > value) {
				this.editForm.usedHours = value
			}
		},
		closeEditModal() {
			this.showEditModal = false
		},

		_validateNumbers() {
			const n = (v) => (v === '' || v === null || v === undefined) ? 0 : Number(v)
			this.editForm.totalHours = n(this.editForm.totalHours)
			this.editForm.usedHours = n(this.editForm.usedHours)
			if (!Number.isFinite(this.editForm.totalHours) || this.editForm.totalHours < 0) return '总课时必须是非负数字'
			if (!Number.isFinite(this.editForm.usedHours) || this.editForm.usedHours < 0) return '已用课时必须是非负数字'
			if (this.editForm.usedHours > this.editForm.totalHours) return '已用课时不能大于总课时'
			return ''
		},

		async _updateUserIfNeeded() {
			if (this.editForm.name === this._original.name && this.editForm.phone === this._original.phone) return
			// 需要name/phone更新
			await apiRequest({
				url: getApiUrl(API_CONFIG.ENDPOINTS.USER_UPDATE),
				method: 'PUT',
				header: { 'Content-Type': 'application/json' },
				data: {
					id: this.editForm.id,
					name: this.editForm.name,
					phone: this.editForm.phone,
					role: this.editForm.role // 必须传，后端SQL会更新role
				}
			})
		},

		async _adjustIfNeeded(delta) {
			if (!delta) return
				const token = uni.getStorageSync('token')
			await apiRequest({
				url: getApiUrl(API_CONFIG.ENDPOINTS.LESSON_ADJUST),
					method: 'POST',
					header: {
						'Content-Type': 'application/json',
						'Authorization': `Bearer ${token}`
					},
				data: {
					studentId: this.editForm.id,
					changeValue: delta,
					title: '总课时调整',
					description: delta > 0 ? `增加${delta}课时` : `减少${Math.abs(delta)}课时`
				}
			})
		},

		async _useIfNeeded(deltaUsed) {
			if (!deltaUsed) return
			const token = uni.getStorageSync('token')
			await apiRequest({
				url: getApiUrl('/api/lesson/use'),
				method: 'POST',
				header: {
					'Content-Type': 'application/json',
					'Authorization': `Bearer ${token}`
				},
				data: {
					studentId: this.editForm.id,
					hours: deltaUsed,
					title: '已用课时调整',
					description: `补记使用${deltaUsed}课时`
				}
			})
		},

		async confirmEditStudent() {
			if (this._submitLock) return
			if (!this.editForm.name.trim()) {
				uni.showToast({ title: '请输入学生姓名', icon: 'none' })
				return
			}
			if (!this.editForm.phone.trim()) {
				uni.showToast({ title: '请输入手机号', icon: 'none' })
				return
			}
			const numericErr = this._validateNumbers()
			if (numericErr) {
				uni.showToast({ title: numericErr, icon: 'none' })
				return
			}
			// 业务约束：不支持直接降低总课时或已用课时
			const deltaTotal = this.editForm.totalHours - this._original.totalHours
			const deltaUsed = this.editForm.usedHours - this._original.usedHours
			if (deltaTotal < 0) {
				uni.showToast({ title: '不支持直接减少总课时，请改为课时调整为负数由系统处理', icon: 'none' })
				return
			}
			if (deltaUsed < 0) {
				uni.showToast({ title: '不支持直接减少已用课时', icon: 'none' })
				return
			}

			this._submitLock = true
			uni.showLoading({ title: '更新中...' })
			try {
				// 1) 基本信息更新（必要时）
				await this._updateUserIfNeeded()
				// 2) 课时调整（先增加/减少剩余与总课时）
				if (deltaTotal !== 0) {
					await this._adjustIfNeeded(deltaTotal)
				}
				// 3) 已用课时增加（消耗剩余）
				if (deltaUsed !== 0) {
					await this._useIfNeeded(deltaUsed)
				}
				uni.showToast({ title: '更新成功', icon: 'success' })
					this.closeEditModal()
					this.loadStudents()
			} catch (error) {
				console.error('更新学生失败:', error)
				const msg = (error && error.message) ? error.message : '更新失败，请重试'
				uni.showToast({ title: msg, icon: 'none' })
			} finally {
				this._submitLock = false
				uni.hideLoading()
			}
		}
	}
}
</script>

<style lang="scss" scoped>
.container {
	min-height: 100vh;
	background: radial-gradient(1200rpx 600rpx at 10% 0%, rgba(33, 150, 243, 0.12), transparent 60%),
		linear-gradient(135deg, #0B0F1A 0%, #121725 50%, #1a1f2e 100%);
	padding-bottom: 40rpx;
}

.sticky-header {
	position: sticky;
	top: 0;
	z-index: 50;
	background: linear-gradient(180deg, rgba(18,23,37,.96), rgba(18,23,37,.92) 60%, rgba(18,23,37,0));
	backdrop-filter: saturate(140%);
}

.search-bar {
	padding: 20rpx;
	position: relative;
	height: 88rpx;

	.search-input-wrapper {
		position: absolute;
		left: 50%;
		top: 50%;
		transform: translate(-50%, -50%);
		width: 70%;
		max-width: 500rpx;
	}
	.search-icon {
		position: absolute;
		left: 26rpx;
		top: 50%;
		transform: translateY(-50%);
		font-size: 28rpx;
		opacity: .7;
		z-index: 1;
	}
	.search-input {
		width: 100%;
		height: 88rpx;
		background: linear-gradient(135deg, #141a29 0%, #1b2133 100%);
		border-radius: 44rpx;
		padding: 0 40rpx 0 70rpx;
		font-size: 28rpx;
		color: #FFFFFF;
		border: 2rpx solid rgba(102, 175, 233, .18);
		box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, .25), inset 0 2rpx 8rpx rgba(0, 0, 0, .25);
		box-sizing: border-box;
		&:focus {
			border-color: rgba(0, 184, 212, .5);
			box-shadow: 0 8rpx 28rpx rgba(0, 184, 212, .18), inset 0 2rpx 8rpx rgba(0, 0, 0, .25);
		}
		&::placeholder { color: rgba(170, 180, 190, 0.6); }
	}
}

.filter-section {
	padding: 16rpx 20rpx 8rpx;
	.filter-tabs {
		display: flex;
		background: linear-gradient(135deg, #121827 0%, #161d2d 100%);
		border-radius: 16rpx;
		padding: 8rpx;
		border: 2rpx solid rgba(102, 175, 233, .18);
		box-shadow: inset 0 1rpx 0 rgba(255,255,255,.03);
		.filter-tab {
			flex: 1;
			padding: 16rpx 20rpx;
			text-align: center;
			border-radius: 12rpx;
			transition: all 0.25s ease;
			&.active {
				background: linear-gradient(135deg, #1976D2 0%, #00B8D4 100%);
				box-shadow: 0 6rpx 18rpx rgba(0, 184, 212, .28);
				.tab-text { color: #FFFFFF; font-weight: 600; }
			}
			.tab-text { font-size: 26rpx; color: #AAB4BE; }
		}
	}
}

.stats-cards {
	margin: 20rpx;
	display: flex;
	gap: 20rpx;
	.stat-card {
		flex: 1;
		background: #131a2a;
		border-radius: 18rpx;
		padding: 30rpx 22rpx;
		border: 2rpx solid rgba(102,175,233,.18);
		box-shadow: 0 12rpx 36rpx rgba(0,0,0,.35);
		display: flex; align-items: center;
		.stat-icon {
			width: 68rpx; height: 68rpx; border-radius: 50%;
			background: linear-gradient(135deg, #00B8D4 0%, #1976D2 100%);
			display: flex; align-items: center; justify-content: center; margin-right: 22rpx;
			.icon-text { font-size: 30rpx; }
		}
		.stat-content { flex: 1; }
		.stat-number { display: block; font-size: 34rpx; color: #fff; font-weight: 800; letter-spacing: .5rpx; }
		.stat-label { font-size: 22rpx; color: #AAB4BE; }
	}
}

.gradient-text {
	background: linear-gradient(90deg, #6ee7f9, #60a5fa, #a78bfa);
	-webkit-background-clip: text; background-clip: text; color: transparent;
}

/* 骨架屏 */
.skeleton-list { margin: 20rpx; display: grid; gap: 20rpx; }
.skeleton-item { display: flex; gap: 20rpx; background: #141b2c; border: 2rpx solid rgba(102,175,233,.16); border-radius: 16rpx; padding: 26rpx; }
.skeleton-avatar { width: 80rpx; height: 80rpx; border-radius: 50%; background: #1f2740; }
.skeleton-lines { flex: 1; display: grid; gap: 14rpx; align-content: center; }
.skeleton-line { height: 24rpx; border-radius: 12rpx; background: #1f2740; }
@keyframes shimmer { 0%{opacity:.5} 50%{opacity:.9} 100%{opacity:.5} }
.shimmer { animation: shimmer 1.6s ease-in-out infinite; }

.student-list { margin: 20rpx; }

.student-item {
	background: linear-gradient(180deg, #141b2c, #121827);
	border-radius: 18rpx;
	padding: 26rpx;
	margin-bottom: 20rpx;
	display: flex; justify-content: space-between; align-items: center;
	border: 2rpx solid rgba(102, 175, 233, .18);
	box-shadow: 0 16rpx 36rpx rgba(0,0,0,.35);
	animation: fadeUp .35s ease both;

	.student-info { display: flex; align-items: center; flex: 1; }
	.student-avatar-wrap { position: relative; width: 86rpx; height: 86rpx; margin-right: 22rpx; }
	.student-avatar { width: 86rpx; height: 86rpx; border-radius: 50%; }
	.avatar-ring { position: absolute; inset: 0; border-radius: 50%; border: 4rpx solid rgba(0,184,212,.38); box-shadow: 0 0 0 6rpx rgba(0,184,212,.08) inset; pointer-events: none; }

	.student-details { flex: 1; }
	.student-header { display: flex; align-items: center; margin-bottom: 10rpx; gap: 12rpx; }
	.student-name { font-size: 32rpx; color: #FFFFFF; font-weight: 800; letter-spacing: .5rpx; }
	.student-status { padding: 8rpx 14rpx; border-radius: 20rpx; font-size: 22rpx; font-weight: 700; border: 1rpx solid transparent; }
	.student-status.active { background: rgba(0, 184, 212, 0.18); border-color: #00B8D4; color: #00E5FF; }
	.student-status.inactive { background: rgba(255, 152, 0, 0.16); border-color: #ff9800; color: #FFC074; }
	.glow { box-shadow: 0 8rpx 18rpx rgba(0, 184, 212, .12); }

	.student-phone { display: block; font-size: 26rpx; color: #AAB4BE; margin-bottom: 10rpx; }
	.student-hours { display: flex; gap: 22rpx; flex-wrap: wrap; }
	.hours-item { font-size: 24rpx; color: #AAB4BE; }
	.hours-item.remaining { color: #00E5FF; font-weight: 700; }

	.progress-row { display: flex; align-items: center; gap: 16rpx; margin-top: 14rpx; }
	.progress-bar { position: relative; flex: 1; height: 16rpx; border-radius: 12rpx; background: #1e2741; overflow: hidden; border: 2rpx solid rgba(102,175,233,.18); }
	.progress-fill { position: absolute; left: 0; top: 0; bottom: 0; background: linear-gradient(90deg, #00B8D4, #1976D2); box-shadow: 0 0 10rpx rgba(0,184,212,.6); }
	.progress-text { font-size: 22rpx; color: #AAB4BE; }
	}

.student-actions { display: flex; gap: 16rpx; }
		.action-btn {
	padding: 14rpx 24rpx; border-radius: 22rpx; font-size: 24rpx; border: 2rpx solid transparent;
	transition: transform .12s ease, box-shadow .2s ease, background .2s ease;
}
.action-btn:active { transform: translateY(2rpx) scale(.98); }
.action-btn.edit-btn { background: rgba(0, 184, 212, 0.16); border-color: rgba(0,184,212,.35); color: #8FE9FF; box-shadow: 0 6rpx 16rpx rgba(0, 184, 212, .18); }
.action-btn.detail-btn { background: rgba(255, 152, 0, 0.16); border-color: rgba(255,152,0,.35); color: #FFD39B; box-shadow: 0 6rpx 16rpx rgba(255, 152, 0, .18); }

/* 空状态 */
.empty-section { text-align: center; padding: 80rpx 20rpx; }
.empty-icon { font-size: 120rpx; display: block; margin-bottom: 20rpx; opacity: .5; }
.empty-text { font-size: 34rpx; color: #FFFFFF; font-weight: 800; margin-bottom: 14rpx; letter-spacing: .5rpx; }
.empty-desc { font-size: 26rpx; color: #AAB4BE; }

/* 弹窗 */
.modal { position: fixed; inset: 0; background: rgba(0,0,0,.55); display:flex; align-items:center; justify-content:center; z-index: 999; backdrop-filter: blur(6rpx) saturate(120%); }
.fade-in { animation: fadeIn .2s ease both; }
.slide-up { animation: slideUp .24s ease both; }
@keyframes fadeIn { from { opacity: 0 } to { opacity: 1 } }
@keyframes slideUp { from { opacity:0; transform: translateY(18rpx) scale(.98) } to { opacity:1; transform: translateY(0) scale(1) } }

.modal-content { background: #131a2a; border-radius: 22rpx; width: 92%; max-width: 640rpx; max-height: 82vh; overflow-y: auto; border: 2rpx solid rgba(102,175,233,.2); box-shadow: 0 24rpx 64rpx rgba(0,0,0,.5); }
.modal-header { display: flex; justify-content: space-between; align-items: center; padding: 26rpx 30rpx; border-bottom: 2rpx solid rgba(102,175,233,.12); }
.modal-title { font-size: 34rpx; color: #FFFFFF; font-weight: 800; letter-spacing: .5rpx; }
.modal-close { font-size: 40rpx; color: #AAB4BE; line-height: 1; }

.modal-summary { display:flex; gap: 18rpx; padding: 22rpx 30rpx 10rpx; align-items:center; }
.summary-avatar { width: 84rpx; height: 84rpx; border-radius: 50%; overflow: hidden; border: 3rpx solid rgba(102,175,233,.25); box-shadow: 0 6rpx 16rpx rgba(0,0,0,.35); }
.summary-avatar .avatar { width: 100%; height: 100%; }
.summary-info { flex:1; }
.summary-name { display:block; font-size: 30rpx; color:#fff; font-weight: 800; }
.summary-phone { display:block; font-size: 24rpx; color:#AAB4BE; margin-top: 4rpx; }
.summary-chips { display:flex; gap: 12rpx; margin-top: 10rpx; flex-wrap: wrap; }
.chip { padding: 8rpx 14rpx; border-radius: 16rpx; background: rgba(148, 163, 184, .12); color: #cbd5e1; border: 2rpx solid rgba(148, 163, 184, .24); font-size: 22rpx; }
.chip.primary { background: rgba(0, 184, 212, .12); color: #8FE9FF; border-color: rgba(0, 184, 212, .32); }

.form { padding: 6rpx 30rpx 10rpx; }
.form-item { margin-bottom: 22rpx; }
.form-label { display:block; font-size: 26rpx; color:#fff; margin-bottom: 12rpx; font-weight: 600; }
.input-wrapper { position: relative; }
.prefix { position:absolute; left: 18rpx; top: 50%; transform: translateY(-50%); font-size: 26rpx; opacity: .8; }
.form-input { width: 100%; height: 84rpx; background: linear-gradient(135deg, #1a2134 0%, #1f2840 100%); border-radius: 16rpx; padding: 0 24rpx 0 58rpx; font-size: 28rpx; color: #FFFFFF; border: 2rpx solid rgba(102,175,233,.18); transition: all .25s ease; box-shadow: inset 0 2rpx 8rpx rgba(0, 0, 0, 0.25); }
.form-input:focus { border-color: rgba(0,184,212,.5); box-shadow: 0 0 0 4rpx rgba(0, 184, 212, .18), inset 0 2rpx 8rpx rgba(0, 0, 0, 0.25); }

.two-col { display:grid; grid-template-columns: 1fr 1fr; gap: 20rpx; }
.with-stepper { display:flex; align-items: center; gap: 8rpx; }
.stepper { width: 64rpx; height: 64rpx; border-radius: 14rpx; background: #1a2134; color:#8FE9FF; border: 2rpx solid rgba(102,175,233,.25); font-size: 32rpx; display:flex; align-items:center; justify-content:center; }
.stepper:active { transform: translateY(2rpx); }

.form-calculated { height: 84rpx; line-height: 84rpx; padding: 0 24rpx; font-size: 28rpx; color: #00B8D4; background: rgba(0, 184, 212, 0.1); border-radius: 16rpx; border: 2rpx solid rgba(0, 184, 212, 0.3); font-weight: bold; }

.modal-actions { display: flex; gap: 20rpx; padding: 18rpx 30rpx 26rpx; border-top: 2rpx solid rgba(102,175,233,.12); }
.cancel-btn, .confirm-btn { flex:1; height: 80rpx; border-radius: 40rpx; font-size: 28rpx; border: none; }
.cancel-btn { background: #1a2134; color: #AAB4BE; border: 2rpx solid rgba(102,175,233,.18); }
.confirm-btn { background: linear-gradient(135deg, #1976D2 0%, #00B8D4 100%); color: #FFFFFF; box-shadow: 0 12rpx 28rpx rgba(0,184,212,.28); }
.confirm-btn[disabled] { opacity: .7 }

/* 动画 */
@keyframes fadeUp {
	from { opacity: 0; transform: translateY(12rpx); }
	to { opacity: 1; transform: translateY(0); }
}
</style> 
